#pragma once

#include "BaseTypePublic.h"


namespace BaseType
{

    enum UIDataType
    {
        UnkownType = 0,

        IntType,
        Uint32Type,
        FloatType,
        StringType,
        PointType,
        RectType,
        SizeType,
        BoolType,
        ColorType,
        ObjectType,
        AttriType,

        EventType = 100,
    };

    template<typename T>
    struct Nullable
    {
        T val;
        bool hasVal;

        typedef Nullable<T> MyType;

        Nullable()
        {
            val = T();
            hasVal = false;
        }

        Nullable(T v)
        {
            val = v;
            hasVal = true;
        }

        Nullable(const MyType& v)
        {
            val = v.val;
            hasVal = v.hasVal;
        }

        void Reset()
        {
            val = T();
            hasVal = false;
        }

        bool HasValue() const
        {
            return hasVal;
        }

        T GetValue() const
        {
            return val;
        }

        T GetValueOrDefault(T defVal) const
        {
            if (!HasValue())
            {
                return defVal;
            }
            else
            {
                return val;
            }
        }

        MyType& operator=(T v)
        {
            val = v;
            hasVal = true;
            return *this;
        }

        MyType& operator=(const MyType& v)
        {
            if (this != &v)
            {
                val = v.val;
                hasVal = v.hasVal;
            }

            return *this;
        }

        operator T()
        {
            return val;
        }
    };

    typedef Nullable<int32_t> IntNullable;
    typedef Nullable<uint32_t> UintNullable;
    typedef Nullable<time_t> TimetNullable;
    typedef Nullable<float> FloatNullable;

    struct BASE_TYPE_API IntPtr
    {
        void* value;
        static IntPtr Zero;

        IntPtr() : value(NULL)
        {
        }

        IntPtr(void* v) : value(v)
        {
        }

        IntPtr(const IntPtr& Other) : value(Other.value)
        {
        }

        operator void* ()
        {
            return value;
        }

        IntPtr& operator=(const IntPtr& Other)
        {
            if (&Other != this)
            {
                value = Other.value;
            }
            return *this;
        }

        bool operator==(const IntPtr& Other)
        {
            return (value == Other.value);;
        }

        bool operator!=(const IntPtr& Other)
        {
            return (value != Other.value);;
        }

        bool IsZero() const
        {
            return NULL == value;
        }
    };

}